package com.efast.dmom.mgmt.service.les.impl;

import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import com.efast.cafe.framework.exception.ServiceException;
import com.efast.cafe.framework.jdbc.JdbcDao;
import com.efast.cafe.framework.redis.ObjectRedisTemplate;
import com.efast.cafe.framework.util.SpringWebUtils;
import com.efast.dmom.mgmt.bean.les.GroundingBean;
import com.efast.dmom.mgmt.dao.les.*;
import com.efast.dmom.mgmt.dao.master.TmBasDeliveryUnitDao;
import com.efast.dmom.mgmt.dao.master.TmBasPartDao;
import com.efast.dmom.mgmt.dao.master.TmBasSupplDao;
import com.efast.dmom.mgmt.dao.master.TrBasPartSupplDao;
import com.efast.dmom.mgmt.entity.les.*;
import com.efast.dmom.mgmt.entity.master.TmBasDeliveryUnit;
import com.efast.dmom.mgmt.entity.master.TmBasPart;
import com.efast.dmom.mgmt.entity.master.TmBasSuppl;
import com.efast.dmom.mgmt.entity.master.TrBasPartSuppl;
import com.efast.dmom.mgmt.service.les.TwInbTaskDetailService;
import com.efast.dmom.mgmt.service.mes.TwBasLotService;
import com.efast.dmom.mgmt.utils.Assist;

/**
 * @author chlp
 */
@Service
public class TwInbTaskDetailServiceImpl implements TwInbTaskDetailService {

	/**
	 * 分配记录 TW_INBOUND_ALLOC_DETAIL
	 */
	private final TwInboundAllocDetailDao twInboundAllocDetailDao;
	/**
	 * 库存表 TW_INV_SKU_LOC_T_L
	 */
	private final TwInvSkuLoctlDao twInvSkuLoctlDao;
	/**
	 * 上架任务表 TW_INB_TASK_HEADER
	 */
	private final TwInbTaskHeaderDao twInbTaskHeaderDao;
	/**
	 * 上架任务表 TW_INB_TASK_DETIAIL
	 */
	private final TwInbTaskDetailDao twInbTaskDetailDao;
	/**
	 * 入库记录 TT_WHM_STOCK_INBOUND
	 */
	private final TtWhmStockInboundDao ttWhmStockInboundDao;
	/**
	 * 收货单TW_DOC_ASN_HEADER
	 */
	private final TwDocAsnDetailsDao twDocAsnDetailsDao;
	/**
	 * 收货单TW_DOC_ASN_HEADER
	 */
	private final TwDocAsnHeaderDao twDocAsnHeaderDao;
	/**
	 * 零件仓储关系以及动态库位入库选择规则 tr_bas_part_storage
	 */
	private final TrBasPartStorageDao trBasPartStorageDao;
	/**
	 * 零件主数据信息 tr_bas_part
	 */
	private final TmBasPartDao trBasPartDao;
	/**
	 * 配送单位基本信息 tm_bas_delivery_unit
	 */
	private final TmBasDeliveryUnitDao tmBasDeliveryUnitDao;
	/**
	 * 供应商基本信息 tm_bas_suppl
	 */
	private final TmBasSupplDao tmBasSupplDao;
	/**
	 * 零件供应商关系 tr_bas_part_suppl
	 */
	private final TrBasPartSupplDao trBasPartSupplDao;
	/**
	 * TW_QUALITY_TASK_DETAIL---质检任务子表
	 */
	private final TwQualityTaskHeaderMapper twQualityTaskHeaderMapper;
	/**
	 * TW_QUALITY_TASK_HEADER---质检任务头表
	 */
	private final TwQualityTaskDetailMapper twQualityTaskDetailMapper;
	/**
	 * TW_PACKTRAN_TASK_DETAIL---翻包任务子表
	 */
	private final TwPacktranTaskDetailMapper twPacktranTaskDetailMapper;
	/**
	 * TW_PACKTRAN_TASK_HEADER---翻包任务头表
	 */
	private final TwPacktranTaskHeaderMapper twPacktranTaskHeaderMapper;
	/**
	 * TM_BAS_PART_PACK_HEADER---翻包主数据头表
	 */
	private final TmBasPartPackHeaderMapper tmBasPartPackHeaderMapper;
	/**
	 * TM_BAS_PART_PACK_DETAIL---翻包主数据子表
	 */
	private final TmBasPartPackDetailMapper tmBasPartPackDetailMapper;
	@Qualifier("jdbcDao")
	@Autowired
	private JdbcDao jdbcDao;
	private final ObjectRedisTemplate objectRedisTemplate;
	@Autowired
	private TwBasLotService twBasLotService;

	@Autowired
	public TwInbTaskDetailServiceImpl(TwDocAsnHeaderDao twDocAsnHeaderDao,
			TwInboundAllocDetailDao twInboundAllocDetailDao, TwInvSkuLoctlDao twInvSkuLoctlDao,
			ObjectRedisTemplate objectRedisTemplate, TwInbTaskHeaderDao twInbTaskHeaderDao,
			TwInbTaskDetailDao twInbTaskDetailDao, TtWhmStockInboundDao ttWhmStockInboundDao,
			TwDocAsnDetailsDao twDocAsnDetailsDao, TrBasPartStorageDao trBasPartStorageDao, TmBasPartDao trBasPartDao,
			TmBasDeliveryUnitDao tmBasDeliveryUnitDao, TmBasSupplDao tmBasSupplDao, TrBasPartSupplDao trBasPartSupplDao,
			TwQualityTaskHeaderMapper twQualityTaskHeaderMapper, TwQualityTaskDetailMapper twQualityTaskDetailMapper,
			TwPacktranTaskDetailMapper twPacktranTaskDetailMapper,
			TwPacktranTaskHeaderMapper twPacktranTaskHeaderMapper, TmBasPartPackHeaderMapper tmBasPartPackHeaderMapper,
			TmBasPartPackDetailMapper tmBasPartPackDetailMapper) {
		this.twDocAsnHeaderDao = twDocAsnHeaderDao;
		this.twInboundAllocDetailDao = twInboundAllocDetailDao;
		this.twInvSkuLoctlDao = twInvSkuLoctlDao;
		this.objectRedisTemplate = objectRedisTemplate;
		this.twInbTaskHeaderDao = twInbTaskHeaderDao;
		this.twInbTaskDetailDao = twInbTaskDetailDao;
		this.ttWhmStockInboundDao = ttWhmStockInboundDao;
		this.twDocAsnDetailsDao = twDocAsnDetailsDao;
		this.trBasPartStorageDao = trBasPartStorageDao;
		this.trBasPartDao = trBasPartDao;
		this.tmBasDeliveryUnitDao = tmBasDeliveryUnitDao;
		this.tmBasSupplDao = tmBasSupplDao;
		this.trBasPartSupplDao = trBasPartSupplDao;
		this.twQualityTaskHeaderMapper = twQualityTaskHeaderMapper;
		this.twQualityTaskDetailMapper = twQualityTaskDetailMapper;
		this.twPacktranTaskDetailMapper = twPacktranTaskDetailMapper;
		this.twPacktranTaskHeaderMapper = twPacktranTaskHeaderMapper;
		this.tmBasPartPackHeaderMapper = tmBasPartPackHeaderMapper;
		this.tmBasPartPackDetailMapper = tmBasPartPackDetailMapper;
	}

	/**
	 * 确认上架 设计到的表 d) 分配记录 TW_INBOUND_ALLOC_DETAIL e) 库存表 TW_INV_SKU_LOC_T_L f) 上架任务表
	 * TW_INB_TASK_HEADER、TW_INB_TASK_DETIAIL
	 *
	 * 新任务时可上架箱数和待上架箱数数量是一致的，不可编辑；能编辑的只有实际上架库位和可上架数量；可上架数量小于待上架数量时候，点击上架是部分上架，相等时任务完成。 可上架的数量 在后台没有这个字段，用
	 * 实际上架数量（act_nbound_qty） 字段接受 可上架的箱数 在后台没有这个字段，用 实际上架箱数（act_inb_pack_num） 字段接受
	 */
	@Override
	public synchronized void grounding(GroundingBean groundingBean) {

		List<TwInbTaskDetail> listTwInbTaskDetail = groundingBean.getTwInbTaskDetail();
		TwInbTaskHeader twInbTaskHeader = groundingBean.getTwInbTaskHeader();
		List<TwInbTaskDetail> dbListTwInbTaskDetail = twInbTaskDetailDao.selectTwInbTaskDetail(
				new Assist(Assist.andEq("tw_inb_task_header_id", twInbTaskHeader.getTwInbTaskHeaderId())));
		if (dbListTwInbTaskDetail.size() == 0 || listTwInbTaskDetail.size() == 0) {
			throw new ServiceException(twInbTaskHeader.getAsnSheetNo() + "无法找到detail");
		}

		// 防止表单重复提交
		if (objectRedisTemplate.hasKey(twInbTaskHeader.getAsnSheetNo())) {
			throw new ServiceException(twInbTaskHeader.getAsnSheetNo() + "重复上架");
		}

		boolean a = false;
		for (int i = 0; i < listTwInbTaskDetail.size(); i++) {
			TwInbTaskDetail reqTwInbTaskDetail = listTwInbTaskDetail.get(i);
			TwInbTaskDetail dbTwInbTaskDetail = dbListTwInbTaskDetail.get(i);
			if (!dbTwInbTaskDetail.getPartNoVersion().equals(reqTwInbTaskDetail.getPartNoVersion())) {
				throw new ServiceException("传递数据不对，请先选择行");
			}

			if (reqTwInbTaskDetail.getActNboundQty() <= 0 || reqTwInbTaskDetail.getActInbPackNum() <= 0) {
				throw new ServiceException("实际上架数量或箱数不能小于等于0");
			}
			if (reqTwInbTaskDetail.getActNboundQty() > dbTwInbTaskDetail.getPreNboundQty()
					|| reqTwInbTaskDetail.getActInbPackNum() > dbTwInbTaskDetail.getPreInbPackNum()) {
				throw new ServiceException(dbTwInbTaskDetail.getPartNoVersion() + "实际上架数量或箱数不能大于预期数量或箱数");
			}

			// 【2】：更新 上架任务表 明细--TW_INB_TASK_DETIAIL
			TwInbTaskDetail updatetwinbtaskdetail = new TwInbTaskDetail();
			updatetwinbtaskdetail.setTwInbTaskDetailId(dbTwInbTaskDetail.getTwInbTaskDetailId());
			if (reqTwInbTaskDetail.getActNboundQty() < dbTwInbTaskDetail.getPreNboundQty()) {
				// 上架状态（新任务0，任务完成1,部分上架2,关闭3）
				updatetwinbtaskdetail.setInboundStatus("2");
				a = true;
			}
			if (reqTwInbTaskDetail.getActNboundQty().equals(dbTwInbTaskDetail.getPreNboundQty())) {
				// 上架状态（新任务0，任务完成1,部分上架2,关闭3）
				updatetwinbtaskdetail.setInboundStatus("1");
			}
			// 实际上架数量
			updatetwinbtaskdetail.setActNboundQty(reqTwInbTaskDetail.getActNboundQty());
			// 实际上架箱数
			updatetwinbtaskdetail.setActInbPackNum(reqTwInbTaskDetail.getActInbPackNum());
			// 实际上架仓储单元ID
			updatetwinbtaskdetail.setActTmBasStorageId(reqTwInbTaskDetail.getActTmBasStorageId());
			// 实际上架仓储单元 编号
			updatetwinbtaskdetail.setActTmBasStorageNo(reqTwInbTaskDetail.getActTmBasStorageNo());
			twInbTaskDetailDao.updateNonEmptyTwInbTaskDetailById(updatetwinbtaskdetail);

			// 【3】：更新 分配记录--TW_INBOUND_ALLOC_DETAIL 为上架完成
			TwInboundAllocDetail twInboundAllocDetail = new TwInboundAllocDetail();
			twInboundAllocDetail.setTwInboundAllocDetailId(reqTwInbTaskDetail.getTwInboundAllocDetailId());
			// 状态（已分配0，已生成上架任务1，已完成上架2，部分上架3，无法分配4，关闭5，冲销6）
			twInboundAllocDetail.setItemStatus("2");
			// 实际上架仓储单元ID
			twInboundAllocDetail.setActTmBasStorageId(reqTwInbTaskDetail.getActTmBasStorageId());
			// 实际上架数量
			twInboundAllocDetail.setActNboundQty(reqTwInbTaskDetail.getActNboundQty());
			// 实际上架箱数
			twInboundAllocDetail.setActInbPackNum(reqTwInbTaskDetail.getActInbPackNum());
			twInboundAllocDetailDao.updateNonEmptyTwInboundAllocDetailById(twInboundAllocDetail);

			// 【4】：更新 【stage库位】库存表--TW_INV_SKU_LOC_T_L 库存数量
			TwInvSkuLoctl twInvSkuLoctl = new TwInvSkuLoctl();
			// 箱数
			twInvSkuLoctl.setPackageNum(1);
			// 可用数量-AVAILABLE_QTY
			twInvSkuLoctl.setAvailableQty(0);
			// 库存数量-CUR_QTY
			twInvSkuLoctl.setCurQty(0);
			// 待入库数量-R_INB_QTY
			twInvSkuLoctl.setrInbQty(0);
			// ASN待入库上架数量-ASN_R_INB_QTY
			twInvSkuLoctl.setAsnrInbQty(0);
			twInvSkuLoctl.setTmBasStorageId(reqTwInbTaskDetail.getStageBasStorageId());
			twInvSkuLoctlDao.updateNonEmptyTwInvSkuLoctl(twInvSkuLoctl,
					new Assist(
							Assist.andEq("tw_inv_sku_loc_t_l.tm_bas_storage_id",
									reqTwInbTaskDetail.getStageBasStorageId()),
							Assist.andEq("tw_inv_sku_loc_t_l.part_no_version", reqTwInbTaskDetail.getPartNoVersion())));

			// 【5】：更新【实际上架库位】的库存数量--TW_INV_SKU_LOC_T_L
			TwInvSkuLoctl twInvSkuLoctl1 = new TwInvSkuLoctl();
			// 可用数量-AVAILABLE_QTY
			twInvSkuLoctl1.setAvailableQty(reqTwInbTaskDetail.getActNboundQty());
			// 箱数
			twInvSkuLoctl.setPackageNum(1);
			// 库存数量-CUR_QTY
			twInvSkuLoctl1.setCurQty(reqTwInbTaskDetail.getActNboundQty());
			// 待入库数量-R_INB_QTY
			twInvSkuLoctl1.setrInbQty(0);
			// ASN待入库上架数量-ASN_R_INB_QTY
			twInvSkuLoctl1.setAsnrInbQty(0);
			twInvSkuLoctlDao.updateNonEmptyTwInvSkuLoctl(twInvSkuLoctl1, new Assist(
					Assist.andEq("tw_inv_sku_loc_t_l.tm_bas_storage_id", reqTwInbTaskDetail.getActTmBasStorageId()),
					Assist.andEq("tw_inv_sku_loc_t_l.part_no_version", reqTwInbTaskDetail.getPartNoVersion()),
					Assist.andEq("tw_inv_sku_loc_t_l.part_pack_serial", dbTwInbTaskDetail.getPartPackSerial())));

			// 【6】：插入 入库记录--TT_WHM_STOCK_INBOUND
			List<TwDocAsnHeader> listTwDocAsnHeader = twDocAsnHeaderDao.selectTwDocAsnHeader(
					new Assist(Assist.andEq("tw_doc_asn_header.asn_sheet_no", twInbTaskHeader.getAsnSheetNo())));
			List<TwDocAsnDetails> listTwDocAsnDetails = twDocAsnDetailsDao.selectTwDocAsnDetails(new Assist(
					Assist.andEq("tw_doc_asn_details.tw_doc_asn_header_id",
							listTwDocAsnHeader.get(0).getTwDocAsnHeaderId()),
					Assist.andEq("tw_doc_asn_details.part_no_version", reqTwInbTaskDetail.getPartNoVersion())));
			List<TrBasPartStorage> listTrBasPartStorage = trBasPartStorageDao.selectTrBasPartStorage(new Assist(
					Assist.andEq("tr_bas_part_storage.tr_bas_part_suppl_id",
							listTwDocAsnDetails.get(0).getTrBasPartSupplId()),
					Assist.andEq("tr_bas_part_storage.part_no_version", reqTwInbTaskDetail.getPartNoVersion())));
			if (listTrBasPartStorage.size() == 0) {
				throw new ServiceException(reqTwInbTaskDetail.getPartNoVersion() + "没有查询到零件仓库关系");
			}

			TtWhmStockInbound ttWhmStockInbound = new TtWhmStockInbound();
			// 零件供应商关系ID
			ttWhmStockInbound.setTrBasPartSupplId(listTwDocAsnDetails.get(0).getTrBasPartSupplId());
			// 入库数量
			ttWhmStockInbound.setInboundQty(reqTwInbTaskDetail.getActNboundQty());
			// 入库人
			ttWhmStockInbound.setInboundUsername(SpringWebUtils.getRequestUser());
			// 入库时间
			ttWhmStockInbound.setInboundTime(new Date());
			// 零件批次号
			ttWhmStockInbound.setStockPartLotNo(dbListTwInbTaskDetail.get(i).getLotNo());
			// 对应单证类型
			ttWhmStockInbound.setCommonSheetType(listTwDocAsnHeader.get(0).getCommonSheetType());
			// 仓库id
			ttWhmStockInbound.setWarehouseId(listTrBasPartStorage.get(0).getWarehouseId());
			// 库区
			ttWhmStockInbound.setDlocId(listTrBasPartStorage.get(0).getDlocId());
			// 库位
			ttWhmStockInbound.setLocId(reqTwInbTaskDetail.getActTmBasStorageId());
			// 工厂
			ttWhmStockInbound.setTmBasPlantId(listTrBasPartStorage.get(0).getTmBasPlantId());
			// 车间
			ttWhmStockInbound.setTmBasWorkshopId(listTrBasPartStorage.get(0).getTmBasWorkshopId());
			// 对应单证编号
			ttWhmStockInbound.setSheetNo(reqTwInbTaskDetail.getAsnSheetNo());
			ttWhmStockInbound.setDlocPackageSysid(listTwDocAsnDetails.get(0).getPartPackageId());
			// 当前箱数
			ttWhmStockInbound.setCurPackageNum(reqTwInbTaskDetail.getActInbPackNum());
			// 是否已上传SAP
			ttWhmStockInbound.setIsTosap("0");
			// 是否允许上传SAP0不允许1允许
			ttWhmStockInbound.setIsCanTosap("1");
			// 存储地点==上架库位的编号
			ttWhmStockInbound.setStorageNo(listTrBasPartStorage.get(0).getLocNo());
			// 拉动单类型
			ttWhmStockInbound.setPoType(listTwDocAsnDetails.get(0).getCustSheetType());
			List<TmBasPart> listTmBasPart = trBasPartDao.selectTmBasPart(
					new Assist(Assist.andEq("part_no_version", reqTwInbTaskDetail.getPartNoVersion())));
			// 零件ID
			ttWhmStockInbound.setTmBasPartId(listTmBasPart.get(0).getTmBasPartId());
			List<TmBasDeliveryUnit> listTmBasDeliveryUnit = tmBasDeliveryUnitDao.selectTmBasDeliveryUnit(
					new Assist(Assist.andEq("delivery_unit_no", listTwDocAsnDetails.get(0).getDeliverySend())));
			// 发货地
			ttWhmStockInbound.setDeliverySend(listTmBasDeliveryUnit.get(0).getTmBasDeliveryUnitId());
			List<TmBasDeliveryUnit> listTmBasDeliveryUnit2 = tmBasDeliveryUnitDao.selectTmBasDeliveryUnit(
					new Assist(Assist.andEq("delivery_unit_no", listTwDocAsnDetails.get(0).getDeliverySend())));
			// 收货地
			ttWhmStockInbound.setTmBasDeliveryUnitId(listTmBasDeliveryUnit2.get(0).getTmBasDeliveryUnitId());
			List<TmBasSuppl> listTmBasSuppl = tmBasSupplDao.selectTmBasSuppl(
					new Assist(Assist.andEq("suppl_no", listTwDocAsnDetails.get(0).getSupplNo())));
			// 供应商本地标识码
			ttWhmStockInbound.setTmBasSupplId(listTmBasSuppl.get(0).getTmBasSupplId());
			ttWhmStockInbound.setSupplNo(dbListTwInbTaskDetail.get(i).getSupplNo());
			// 冲销标记
			ttWhmStockInbound.setFlag(0);
			ttWhmStockInbound.setPartNoVersion(reqTwInbTaskDetail.getPartNoVersion());
			ttWhmStockInbound.setBaseUnit(listTwDocAsnDetails.get(0).getBaseUnit());
			ttWhmStockInbound.setSheetLineNo(String.valueOf(listTwDocAsnDetails.get(0).getAsnLineno()));
			// 仓库编号
			ttWhmStockInbound.setWarehouseNo(listTrBasPartStorage.get(0).getWarehouseNo());
			// 库区编号
			ttWhmStockInbound.setDlocNo(listTrBasPartStorage.get(0).getDlocNo());
			// 库位编号
			ttWhmStockInbound.setLocNo(listTrBasPartStorage.get(0).getLocNo());
			ttWhmStockInbound.setMarkStatus(1);
			ttWhmStockInbound.setCompanyCode(SpringWebUtils.getRequestCompany());
			ttWhmStockInbound.setCreateTime(new Date());
			ttWhmStockInbound.setCreateUser(SpringWebUtils.getRequestUser());
			// ttWhmStockInbound.setInBoundGroupId(inBoundGroupId); // 入库组号
			// ttWhmStockInbound.setSheetId(sheetId); // 对应单证ID
			// ttWhmStockInbound.setInterfaceGroupId(interfaceGroupId);// 接口汇总组号
			// ttWhmStockInbound.setVin(vin); // VIN号 预留字段 目前不用
			// ttWhmStockInbound.setToOutboundFalg(toOutboundFalg); // 生成出库记录标记(外排序单)
			ttWhmStockInboundDao.insertNonEmptyTtWhmStockInbound(ttWhmStockInbound);

			// 【7】：从零件供应商关系中查询判断零件是否需要质检。
			List<TrBasPartSuppl> trBasPartSuppls = trBasPartSupplDao.selectTrBasPartSuppl(
					new Assist(Assist.andEq("part_no_version", dbTwInbTaskDetail.getPartNoVersion()),
							Assist.andEq("suppl_no", dbTwInbTaskDetail.getSupplNo())));
			if (trBasPartSuppls.size() == 0) {
				throw new ServiceException(
						dbTwInbTaskDetail.getPartNoVersion() + " " + dbTwInbTaskDetail.getSupplNo() + "没有对应的零件供应商关系");
			}
			// 说明零件需要质检
			List<TrBasPartStorage> trBasPartStorages = trBasPartStorageDao.selectTrBasPartStorage(
					new Assist(Assist.andEq("part_no_version", reqTwInbTaskDetail.getPartNoVersion()),
							Assist.andEq("loc_id", reqTwInbTaskDetail.getActTmBasStorageId())));
			if (trBasPartStorages.size() == 0) {
				throw new ServiceException("零件号和上架库位找不到对应的零件仓库关系");
			}
			// 正常库位+零件 --》零件仓库关系找6个库位类型是否包含质检。
			boolean qualityTesting = false;
			for (TrBasPartStorage trBasPartStorage : trBasPartStorages) {
				if ("4".equals(trBasPartStorage.getLocUseType1())) {
					qualityTesting = true;
				}
				if ("4".equals(trBasPartStorage.getLocUseType2())) {
					qualityTesting = true;
				}
				if ("4".equals(trBasPartStorage.getLocUseType3())) {
					qualityTesting = true;
				}
				if ("4".equals(trBasPartStorage.getLocUseType4())) {
					qualityTesting = true;
				}
				if ("4".equals(trBasPartStorage.getLocUseType5())) {
					qualityTesting = true;
				}
			}
			if ("1".equals(trBasPartSuppls.get(0).getQualityLogo()) && qualityTesting) {
				TwQualityTaskHeader twQualityTaskHeader = new TwQualityTaskHeader();

				twQualityTaskHeader.setAsnSheetNo(dbTwInbTaskDetail.getAsnSheetNo());
				String qualityAllocNo = jdbcDao.executeProcGetCode("tw_quality_task_header", "efast");
				twQualityTaskHeader.setPartSerialNo(dbTwInbTaskDetail.getPartPackSerial());
				twQualityTaskHeader.setQualityAllocNo(qualityAllocNo);
				// 质检任务状态 默认是0 质检任务状态 0新单 1部分质检 2完全质检 3任务关闭）
				twQualityTaskHeader.setQualityStatus("0");
				twQualityTaskHeader.setTaskCreatetime(new Date());
				twQualityTaskHeader.setTaskCreateman(SpringWebUtils.getRequestUser());
				twQualityTaskHeader.setCompanyCode(SpringWebUtils.getRequestCompany());
				twQualityTaskHeader.setCreateTime(new Date());
				twQualityTaskHeader.setCreateUser(SpringWebUtils.getRequestUser());
				twQualityTaskHeader.setMarkStatus(1);
				twQualityTaskHeader.setOptCounter(1);
				twQualityTaskHeaderMapper.insert(twQualityTaskHeader);

				TwQualityTaskDetail twQualityTaskDetail = new TwQualityTaskDetail();
				BeanUtils.copyProperties(dbTwInbTaskDetail, twQualityTaskDetail);
				twQualityTaskDetail.setTwQualityTaskHeaderId(twQualityTaskHeader.getTwQualityTaskHeaderId());
				// 质检任务状态 默认是0 质检任务状态 0新单 1部分质检 2完全质检 3任务关闭）
				twQualityTaskDetail.setQualityStatus("0");
				twQualityTaskDetail.setAsnLineno(1);
				twQualityTaskDetail.setPartNoVersion(dbTwInbTaskDetail.getPartNoVersion());
				twQualityTaskDetail.setInboundPackNo(dbTwInbTaskDetail.getInboundPackNo());
				twQualityTaskDetail.setInbSerialNo(dbTwInbTaskDetail.getInbSerialNo());
				twQualityTaskDetail.setAsnSheetNo(dbTwInbTaskDetail.getAsnSheetNo());
				twQualityTaskDetail.setSupplNo(dbTwInbTaskDetail.getSupplNo());
				twQualityTaskDetail.setPartNameC(dbTwInbTaskDetail.getPartNamec());
				twQualityTaskDetail.setBaseUnit(dbTwInbTaskDetail.getBaseUnit());
				// 预期质检数量
				twQualityTaskDetail.setPreNboundQty(reqTwInbTaskDetail.getActNboundQty());
				twQualityTaskDetail.setLineNo(1);
				// 质检任务单号
				twQualityTaskDetail.setQualityAllocNo(qualityAllocNo);
				// 批次号
				twQualityTaskDetail.setLotNo(dbTwInbTaskDetail.getLotNo());
				// 入库包装容量
				twQualityTaskDetail.setInboundPackQty(dbTwInbTaskDetail.getInboundPackQty());
				// 入库优先级
				twQualityTaskDetail.setInboundPriority(dbTwInbTaskDetail.getInboundPriority());
				// 预期质检箱数 默认是1
				twQualityTaskDetail.setPreQualityPackNum(1);
				// 实际质检箱数 默认是0
				twQualityTaskDetail.setActQualityPackNum(0);
				// 零件包装流水号
				twQualityTaskDetail.setPartPackSerial(dbTwInbTaskDetail.getPartPackSerial());
				// 待收货库位id
				twQualityTaskDetail.setStageBasStorageId(dbTwInbTaskDetail.getPreTmBasStorageId());
				// 实物所在库位
				twQualityTaskDetail.setActTmBasStorageId(reqTwInbTaskDetail.getActTmBasStorageId());
				twQualityTaskDetail.setCompanyCode(SpringWebUtils.getRequestCompany());
				twQualityTaskDetail.setCreateTime(new Date());
				twQualityTaskDetail.setCreateUser(SpringWebUtils.getRequestUser());
				twQualityTaskDetail.setMarkStatus(1);
				twQualityTaskDetail.setOptCounter(1);
				twQualityTaskDetailMapper.insert(twQualityTaskDetail);
			}

			// 【8】：判断是否需要翻包,
			boolean isPack = false;
			for (TrBasPartStorage trBasPartStorage : trBasPartStorages) {
				if ("10".equals(trBasPartStorage.getLocUseType1())) {
					isPack = true;
				}
				if ("10".equals(trBasPartStorage.getLocUseType2())) {
					isPack = true;
				}
				if ("10".equals(trBasPartStorage.getLocUseType3())) {
					isPack = true;
				}
				if ("10".equals(trBasPartStorage.getLocUseType4())) {
					isPack = true;
				}
				if ("10".equals(trBasPartStorage.getLocUseType5())) {
					isPack = true;
				}
			}
			// 零件供应商关系定义了是要翻包的，并且实际上架的库位是库位使用类型包含了“翻包”的类型
			if ("1".equals(trBasPartSuppls.get(0).getIsPack()) && isPack) {
				System.out.println(dbTwInbTaskDetail.getPartNoVersion()+"需要翻包");
				Wrapper<TmBasPartPackHeader> tWrapper = new EntityWrapper<>();
				tWrapper.where("part_no_version={0}", dbTwInbTaskDetail.getPartNoVersion());
				List<TmBasPartPackHeader> tmBasPartPackHeaders = tmBasPartPackHeaderMapper.selectList(tWrapper);
				if (tmBasPartPackHeaders.size() == 0) {
					throw new ServiceException(dbTwInbTaskDetail.getPartNoVersion() + "零件在主数据中没有定义翻包信息");
				}
				EntityWrapper<TmBasPartPackDetail> wrapper = new EntityWrapper<>();
				wrapper.where("tm_bas_part_pack_header_id={0}", tmBasPartPackHeaders.get(0).getTmBasPartPackHeaderId());
				List<TmBasPartPackDetail> tmBasPartPackDetails = tmBasPartPackDetailMapper.selectList(wrapper);
				if (tmBasPartPackDetails.size() == 0) {
					throw new ServiceException(dbTwInbTaskDetail.getPartNoVersion() + "零件在主数据中没有定义翻包信息");
				}
				// a)系统需要考虑1箱有零散剩余的情况，比如1箱10个，翻成4个一包，那么会剩余2个，这两个需要等下次再来1箱后，
				// 和再次剩余的2个组成一包，也就是包含组包的功能
				int i1 = reqTwInbTaskDetail.getActNboundQty() / tmBasPartPackDetails.get(0).getPartQty();

				TwPacktranTaskHeader twPacktranTaskHeader = new TwPacktranTaskHeader();
				// 任务状态 默认为0 翻包任务状态 0新单 1部分翻包 2完全翻包 3任务关闭
				twPacktranTaskHeader.setPacktranStatus("0");
				// 任务单号 P+yyyymmdd+seq
				String s = jdbcDao.executeProcGetCode("tw_packtran_task_header", "efast");
				twPacktranTaskHeader.setPacktranSheetNo(s);
				// 打印状态 默认为0 打印状态0未打印,1部分打印,2打印完成
				twPacktranTaskHeader.setPrintStatus("0");
				// 任务创建时间
				twPacktranTaskHeader.setTaskCreatetime(new Date());
				// 任务创建人
				twPacktranTaskHeader.setTaskCreateman(SpringWebUtils.getRequestUser());
				// ASN序列号
				twPacktranTaskHeader.setAsnSheetNo(dbTwInbTaskDetail.getAsnSheetNo());
				// 零件包装流水号
				twPacktranTaskHeader.setPartSerialNo(dbTwInbTaskDetail.getPartPackSerial());
				twPacktranTaskHeader.setCompanyCode(SpringWebUtils.getRequestCompany());
				twPacktranTaskHeader.setCreateTime(new Date());
				twPacktranTaskHeader.setCreateUser(SpringWebUtils.getRequestUser());
				twPacktranTaskHeader.setMarkStatus(1);
				twPacktranTaskHeader.setOptCounter(1);
				twPacktranTaskHeaderMapper.insert(twPacktranTaskHeader);
				for (int i2 = 0; i2 < i1; i2++) {
					TwPacktranTaskDetail twPacktranTaskDetail = new TwPacktranTaskDetail();
					BeanUtils.copyProperties(dbListTwInbTaskDetail, twInboundAllocDetail);
					// 头表ID
					twPacktranTaskDetail.setTwPacktranTaskHeaderId(twPacktranTaskHeader.getTwPacktranTaskHeaderId());
					// 翻包完成后 分配上架库位时 分配表对应的ID
					// twPacktranTaskDetail.setTwInboundAllocDetailId();
					// 零件号
					twPacktranTaskDetail.setPartNoVersion(dbTwInbTaskDetail.getPartNoVersion());
					// 供应商号
					twPacktranTaskDetail.setSupplNo(dbTwInbTaskDetail.getSupplNo());
					// 零件中文描述
					twPacktranTaskDetail.setPartNameC(dbTwInbTaskDetail.getPartNamec());
					// 基本单位
					twPacktranTaskDetail.setBaseUnit(dbTwInbTaskDetail.getBaseUnit());
					// 翻包状态 翻包任务子状态 0新单 1待打印 2已打印 3任务关闭
					twPacktranTaskDetail.setPacktranStatus("0");
					// 行号 自动递增
					twPacktranTaskDetail.setLineNo(i2+1);
					if (tmBasPartPackDetails.size() == 1) {
						// 包材1
						twPacktranTaskDetail.setPackNo1(tmBasPartPackDetails.get(0).getPackNo());
					}
					if (tmBasPartPackDetails.size() == 2) {
						// 包材2
						twPacktranTaskDetail.setPackNo2(tmBasPartPackDetails.get(1).getPackNo());
					}
					if (tmBasPartPackDetails.size() == 3) {
						// 包材3
						twPacktranTaskDetail.setPackNo3(tmBasPartPackDetails.get(2).getPackNo());
					}
					if (tmBasPartPackDetails.size() == 4) {
						// 包材4
						twPacktranTaskDetail.setPackNo4(tmBasPartPackDetails.get(3).getPackNo());
					}
					if (tmBasPartPackDetails.size() == 5) {
						// 包材5
						twPacktranTaskDetail.setPackNo5(tmBasPartPackDetails.get(4).getPackNo());
					}
					// ASN序列号
					twPacktranTaskDetail.setAsnSheetNo(dbTwInbTaskDetail.getAsnSheetNo());
					// 预期翻包数量 ---1包多少个零件的数量 == 就是翻包主数据里 的 零件数量
					twPacktranTaskDetail.setPreNboundQty(tmBasPartPackDetails.get(0).getPartQty());
					// 实际翻包数量---1包多少个零件的数量
					twPacktranTaskDetail.setActNboundQty(0);
					// 预期翻包箱数
					twPacktranTaskDetail.setPrePackNum(1);
					// 实际翻包箱数 默认是0
					twPacktranTaskDetail.setActPackNum(0);
					// 批次号
					twPacktranTaskDetail.setLotNo(dbTwInbTaskDetail.getLotNo());
					// 零件包装流水号 （翻包的时候产生 P+yyyyMMdd+5）
					twPacktranTaskDetail.setPartPackSerial(s);
					// 入库包装流水号
					twPacktranTaskDetail.setInbSerialNo(dbTwInbTaskDetail.getInbSerialNo());
					// 翻包人
					twPacktranTaskDetail.setPacktranMan(SpringWebUtils.getRequestUser());
					// 翻包时间
					twPacktranTaskDetail.setPacktranTime(new Date());
					// 货主 默认工厂的配送单位
					// twPacktranTaskDetail.setCustomerid();
					// 翻包任务号
					twPacktranTaskDetail.setPacktranSheetNo(s);
					// 实物所在库位ID == 就是当前库位的id(上架到翻包区 才会产生翻包任务,那么现在的库位id 应该就是上架到的那个库位id)
					twPacktranTaskDetail.setActTmBasStorageId(dbTwInbTaskDetail.getActTmBasStorageId());
					// 入库优先级
					twPacktranTaskDetail.setInboundPriority(dbTwInbTaskDetail.getInboundPriority());
					if (tmBasPartPackDetails.size() == 1) {
						// 预期消耗包材1数量 默认是0
						twPacktranTaskDetail.setPrePackQty1(tmBasPartPackDetails.get(0).getPackQty());
						twPacktranTaskDetail.setActPackQty1(0);
					}
					if (tmBasPartPackDetails.size() == 2) {
						// 预期消耗包材1数量 默认是0
						twPacktranTaskDetail.setPrePackQty2(tmBasPartPackDetails.get(1).getPackQty());
						twPacktranTaskDetail.setActPackQty2(0);
					}
					if (tmBasPartPackDetails.size() == 3) {
						// 预期消耗包材1数量 默认是0
						twPacktranTaskDetail.setPrePackQty3(tmBasPartPackDetails.get(2).getPackQty());
						twPacktranTaskDetail.setActPackQty3(0);
					}
					if (tmBasPartPackDetails.size() == 4) {
						// 预期消耗包材1数量 默认是0
						twPacktranTaskDetail.setPrePackQty4(tmBasPartPackDetails.get(3).getPackQty());
						twPacktranTaskDetail.setActPackQty4(0);
					}
					if (tmBasPartPackDetails.size() == 5) {
						// 预期消耗包材1数量 默认是0
						twPacktranTaskDetail.setPrePackQty5(tmBasPartPackDetails.get(4).getPackQty());
						twPacktranTaskDetail.setActPackQty5(0);
					}
					twPacktranTaskDetail.setCompanyCode(SpringWebUtils.getRequestCompany());
					twPacktranTaskDetail.setCreateTime(new Date());
					twPacktranTaskDetail.setCreateUser(SpringWebUtils.getRequestUser());
					twPacktranTaskDetail.setMarkStatus(1);
					twPacktranTaskDetail.setOptCounter(1);
					twPacktranTaskDetailMapper.insert(twPacktranTaskDetail);
				}
			} else {
				System.out.println(dbTwInbTaskDetail.getPartNoVersion() + "不需要翻包");
			}
		}
		// 【1】：更新 上架任务表 头表--TW_INB_TASK_HEADER
		if (a) {
			// 0：新任务 1：任务完成 2：任务部分完成
			twInbTaskHeader.setInboundStatus("2");
		} else {
			// 0：新任务 1：任务完成 2：任务部分完成
			twInbTaskHeader.setInboundStatus("1");
		}
		twInbTaskHeaderDao.updateNonEmptyTwInbTaskHeaderById(twInbTaskHeader);
		objectRedisTemplate.opsForValue().set(twInbTaskHeader.getAsnSheetNo(), "", 2, TimeUnit.SECONDS);
		//打印上架任务清单
		twBasLotService.printGroundingList(dbListTwInbTaskDetail);
	}

	@Override
	public void updateNonEmptyTwInbTaskDetailById(TwInbTaskDetail reqTwInbTaskDetail) {
		twInbTaskDetailDao.updateNonEmptyTwInbTaskDetailById(reqTwInbTaskDetail);
	}

	@Override
	public long getTwInbTaskDetailRowCount(Assist assist) {
		return twInbTaskDetailDao.getTwInbTaskDetailRowCount(assist);
	}

	@Override
	public List<TwInbTaskDetail> selectTwInbTaskDetail(Assist assist) {
		return twInbTaskDetailDao.selectTwInbTaskDetail(assist);
	}

	@Override
	public TwInbTaskDetail selectTwInbTaskDetailByObj(TwInbTaskDetail obj) {
		return twInbTaskDetailDao.selectTwInbTaskDetailByObj(obj);
	}

	@Override
	public TwInbTaskDetail selectTwInbTaskDetailById(Integer id) {
		return twInbTaskDetailDao.selectTwInbTaskDetailById(id);
	}

	@Override
	public int insertTwInbTaskDetail(TwInbTaskDetail value) {
		return twInbTaskDetailDao.insertTwInbTaskDetail(value);
	}

	@Override
	public int insertNonEmptyTwInbTaskDetail(TwInbTaskDetail value) {
		return twInbTaskDetailDao.insertNonEmptyTwInbTaskDetail(value);
	}

	@Override
	public int insertTwInbTaskDetailByBatch(List<TwInbTaskDetail> value) {
		return twInbTaskDetailDao.insertTwInbTaskDetailByBatch(value);
	}

	@Override
	public int deleteTwInbTaskDetailById(Integer id) {
		return twInbTaskDetailDao.deleteTwInbTaskDetailById(id);
	}

	@Override
	public int deleteTwInbTaskDetail(Assist assist) {
		return twInbTaskDetailDao.deleteTwInbTaskDetail(assist);
	}

	@Override
	public int updateTwInbTaskDetailById(TwInbTaskDetail reqTwInbTaskDetail) {
		return twInbTaskDetailDao.updateTwInbTaskDetailById(reqTwInbTaskDetail);
	}

	@Override
	public int updateTwInbTaskDetail(TwInbTaskDetail value, Assist assist) {
		return twInbTaskDetailDao.updateTwInbTaskDetail(value, assist);
	}

	@Override
	public int updateNonEmptyTwInbTaskDetail(TwInbTaskDetail value, Assist assist) {
		return twInbTaskDetailDao.updateNonEmptyTwInbTaskDetail(value, assist);
	}

}